package com.fulihui.systemcore.service;

import com.fulihui.systemcore.api.CityModuleService;
import com.fulihui.systemcore.dto.PosAreaDTO;
import com.fulihui.systemcore.dto.PosCityDTO;
import com.fulihui.systemcore.dto.PosProvinceDTO;
import com.fulihui.systemcore.repository.CityModuleRepository;
import com.fulihui.systemcore.request.citymodule.QueryProvincesCityByNameRequest;
import com.fulihui.systemcore.request.citymodule.SetHotCitiesRequest;
import com.fulihui.systemcore.response.citymodule.LocationResponse;
import org.apache.dubbo.config.annotation.Service;
import org.near.servicesupport.error.CommonServiceErrorEnum;
import org.near.servicesupport.error.InvokeServiceException;
import org.near.servicesupport.request.BaseRequest;
import org.near.servicesupport.request.TRequest;
import org.near.servicesupport.result.BaseResult;
import org.near.servicesupport.result.ResultBuilder;
import org.near.servicesupport.result.TMultiResult;
import org.near.servicesupport.result.TSingleResult;
import org.near.servicesupport.util.ServiceAssert;
import org.near.toolkit.common.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Optional;

/**
 *
 * @author leeson 2016年5月25日 下午12:06:26
 */
@Service(version = "1.0.0")
public class CityModuleServiceImpl implements CityModuleService {
    private final transient Logger LOG = LoggerFactory.getLogger(getClass());
    @Autowired
    private CityModuleRepository   cityModuleRepository;

    @Override
    public TMultiResult<PosProvinceDTO> queryProvince(BaseRequest request) {
        return ResultBuilder.succTMulti(cityModuleRepository.queryProvinceAll());
    }

    @Override
    public TMultiResult<PosCityDTO> queryCity(TRequest<String> request) {
        return ResultBuilder.succTMulti(cityModuleRepository.queryCityAll(request.getCondition()));
    }

    @Override
    public TMultiResult<PosCityDTO> queryCitiesByCodes(TRequest<List<String>> request) {
        return ResultBuilder.succTMulti(cityModuleRepository.queryCitiesByCodes(request
            .getCondition()));
    }

    @Override
    public TMultiResult<PosAreaDTO> queryArea(TRequest<String> request) {
        return ResultBuilder.succTMulti(cityModuleRepository.queryAreaAll(request.getCondition()));
    }

    @Override
    public TSingleResult<LocationResponse> queryByCode(TRequest<String> request) {
        PosProvinceDTO province = cityModuleRepository.queryProvince(request.getCondition());
        if (null != province) {
            LocationResponse location = new LocationResponse();
            location.setProvinceCode(province.getCode());
            location.setProvinceName(province.getName());

            return ResultBuilder.succTSingle(location);
        }

        PosCityDTO city = cityModuleRepository.queryCity(request.getCondition());
        if (null != city) {
            province = cityModuleRepository.queryProvince(city.getProvinceCode());

            LocationResponse location = new LocationResponse();
            location.setProvinceCode(province.getCode());
            location.setProvinceName(province.getName());
            location.setCityCode(city.getCode());
            location.setCityName(city.getName());

            return ResultBuilder.succTSingle(location);
        }

        PosAreaDTO area = cityModuleRepository.queryArea(request.getCondition());
        if (null != area) {
            city = cityModuleRepository.queryCity(area.getCityCode());
            province = cityModuleRepository.queryProvince(city.getProvinceCode());

            LocationResponse location = new LocationResponse();
            location.setProvinceCode(province.getCode());
            location.setProvinceName(province.getName());
            location.setCityCode(city.getCode());
            location.setCityName(city.getName());
            location.setAreaCode(area.getCode());
            location.setAreaName(area.getName());

            return ResultBuilder.succTSingle(location);
        }

        return ResultBuilder.failTSingle(101, "代码无法找到相应地区");
    }

    @Override
    public TSingleResult<PosProvinceDTO> queryProvinceByName(TRequest<String> request) {
        ServiceAssert.notBlank(request.getCondition(),
            CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        return ResultBuilder.succTSingle(queryProvinceByName(request.getCondition()));
    }

    private PosProvinceDTO queryProvinceByName(String queryName) {
        final String name;
        int suffixIdx = queryName.length() - 1;
        // '省','市'结尾去掉后比较
        if (queryName.lastIndexOf("省") == suffixIdx || queryName.lastIndexOf("市") == suffixIdx) {
            name = queryName.substring(0, suffixIdx);
        } else {
            name = queryName;
        }
        List<PosProvinceDTO> provinceList = cityModuleRepository.queryProvinceAll();
        PosProvinceDTO province = null;
        if (!CollectionUtils.isEmpty(provinceList)) {
            Optional<PosProvinceDTO> found = provinceList.stream()
                .filter(it -> it.getName().contains(name)).findFirst();
            if (found.isPresent()) {
                province = found.get();
            }
        }
        return province;
    }

    @Override
    public TSingleResult<PosCityDTO> queryProvincesCityByName(QueryProvincesCityByNameRequest request) {
        if (StringUtil.isBlank(request.getProvinceCode())
            && StringUtil.isBlank(request.getProvinceName())) {
            LOG.error("省份代码和省份名称不能都为空 provinceName:{}, provinceCode:{}", request.getProvinceName(),
                request.getProvinceCode());
            throw new InvokeServiceException(CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        }
        ServiceAssert.notBlank(request.getCityName(),
            CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        String queryName = request.getCityName();
        final String name;
        int suffixIdx = queryName.length() - 1;
        // '市'结尾去掉后比较
        if (queryName.lastIndexOf("市") == suffixIdx) {
            name = queryName.substring(0, suffixIdx);
        } else {
            name = queryName;
        }
        List<PosCityDTO> cityList = null;
        if (StringUtil.isNotBlank(request.getProvinceCode())) {
            cityList = cityModuleRepository.queryCityAll(request.getProvinceCode());
        } else if (StringUtil.isNotBlank(request.getProvinceName())) {
            PosProvinceDTO province = queryProvinceByName(request.getProvinceName());
            if (province != null) {
                cityList = cityModuleRepository.queryCityAll(province.getCode());
            }
        }
        PosCityDTO city = null;
        if (!CollectionUtils.isEmpty(cityList)) {
            Optional<PosCityDTO> found = cityList.stream()
                .filter(it -> it.getName().contains(name)).findFirst();
            if (found.isPresent()) {
                city = found.get();
            }
        }
        return ResultBuilder.succTSingle(city);
    }

    @Override
    public TSingleResult<PosCityDTO> queryCapitalCityByProvinceCode(TRequest<String> request) {
        String provinceCode = request.getCondition();
        if (StringUtil.isBlank(provinceCode)) {
            LOG.error("省份代码不能都为空 provinceCode:{}", provinceCode);
            throw new InvokeServiceException(CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        }
        return ResultBuilder.succTSingle(cityModuleRepository
            .queryCapitalCityByProvinceCode(provinceCode));
    }

    @Override
    public TMultiResult<PosCityDTO> queryHotCities(BaseRequest baseRequest) {
        List<PosCityDTO> posCityList = cityModuleRepository.queryHotCities();
        return ResultBuilder.succTMulti(posCityList);
    }

    @Override
    public BaseResult setHot(SetHotCitiesRequest request) {
        boolean b = cityModuleRepository.setHot(request.getHot(), request.getCodes());
        return b ? ResultBuilder.succ(BaseResult.class) : ResultBuilder.fail(BaseResult.class,
            CommonServiceErrorEnum.SYSTEM_ERROR);
    }

}